home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 28
/
Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso
/
Aminet
/
game
/
board
/
Crafty-15.19.lha
/
crafty-15.19
/
src
/
book.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-09-16
|
50KB
|
1,252 lines
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "chess.h"
#include "data.h"
#if defined(UNIX)
# include <unistd.h>
#endif
/* last modified 08/26/98 */
/*
********************************************************************************
* *
* Book() is used to determine if the current position is in the book data- *
* base. it simply takes the set of moves produced by root_moves() and then *
* tries each position's hash key to see if it can be found in the data- *
* base. if so, such a move represents a "book move." the set of flags is *
* used to decide on a sub-set of moves to be used as the "book move pool" *
* from which a move is chosen randomly. *
* *
* the format of a book position is as follows: *
* *
* 64 bits: hash key for this position. *
* *
* 8 bits: flag bits defined as follows: *
* *
* 0000 0001 ?? flagged move (0001) (0x01) *
* 0000 0010 ? flagged move (0002) (0x02) *
* 0000 0100 = flagged move (0004) (0x04) *
* 0000 1000 ! flagged move (0010) (0x08) *
* 0001 0000 !! flagged move (0020) (0x10) *
* 0010 0000 black won at least 1 game (0040) (0x20) *
* 0100 0000 at least one game was drawn (0100) (0x40) *
* 1000 0000 white won at least 1 game (0200) (0x80) *
* *
* 24 bits: number of games this move was played. *
* *
* 32 bits: learned value (floating point). *
* *
* (note: counts are normalized to a max of 255. *
* *
********************************************************************************
*/
#define BAD_MOVE 002
#define GOOD_MOVE 010
int Book(TREE *tree, int wtm, int root_list_done) {
static int book_moves[200];
static BOOK_POSITION start_moves[200];
static int selected[200];
static int selected_order_played[200], selected_value[200];
static int selected_status[200], selected_percent[200], book_development[200];
static int bs_played[200], bs_percent[200];
static int book_status[200], evaluations[200], bs_learn[200];
static float bs_value[200], total_value;
int m1_status, forced=0, total_percent;
float tempr;
int done, i, j, last_move, temp, which, minlv=999999, maxlv=-999999;
int maxp=-999999, minev=999999, maxev=-999999;
int *mv, mp, value, np;
int cluster, scluster, test;
BITBOARD temp_hash_key, common;
int key, nmoves, num_selected, st;
int percent_played, total_played, total_moves, smoves;
int distribution;
int initial_development;
char *whisper_p;
/*
----------------------------------------------------------
| |
| if we have been out of book for several moves, return |
| and start the normal tree search. |
| |
----------------------------------------------------------
*/
if (moves_out_of_book > 3) return(0);
/*
----------------------------------------------------------
| |
| position is known, read the start book file and save |
| each move found. these will be used later to augment |
| the flags in the normal book to offer better control. |
| |
----------------------------------------------------------
*/
if (!root_list_done) RootMoveList(wtm);
test=HashKey>>49;
smoves=0;
if (books_file) {
fseek(books_file,test*sizeof(int),SEEK_SET);
fread(&key,sizeof(int),1,books_file);
if (key > 0) {
fseek(books_file,key,SEEK_SET);
fread(&scluster,sizeof(int),1,books_file);
fread(books_buffer,sizeof(BOOK_POSITION),scluster,books_file);
for (mv=tree->last[0];mv<tree->last[1];mv++) {
common=And(HashKey,mask_16);
MakeMove(tree,1,*mv,wtm);
if (RepetitionCheck(tree,2,ChangeSide(wtm))) {
UnMakeMove(tree,1,*mv,wtm);
return(0);
}
temp_hash_key=Xor(HashKey,wtm_random[wtm]);
temp_hash_key=Or(And(temp_hash_key,Compl(mask_16)),common);
for (i=0;i<scluster;i++)
if (!Xor(temp_hash_key,books_buffer[i].position)) {
start_moves[smoves++]=books_buffer[i];
break;
}
UnMakeMove(tree,1,*mv,wtm);
}
}
}
/*
----------------------------------------------------------
| |
| position is known, read in the appropriate cluster. |
| note that this cluster will have all possible book |
| moves from current position in it (as well as others |
| of course.) |
| |
----------------------------------------------------------
*/
test=HashKey>>49;
if (book_file) {
fseek(book_file,test*sizeof(int),SEEK_SET);
fread(&key,sizeof(int),1,book_file);
if (key > 0) {
fseek(book_file,key,SEEK_SET);
fread(&cluster,sizeof(int),1,book_file);
fread(book_buffer,sizeof(BOOK_POSITION),cluster,book_file);
}
else cluster=0;
if (!cluster) return(0);
/*
----------------------------------------------------------
| |
| now add any moves from books.bin to the end of the |
| cluster so that they will be played even if not in the |
| regular database of moves. |
| |
----------------------------------------------------------
*/
for (i=0;i<smoves;i++) {
for (j=0;j<cluster;j++)
if (!Xor(book_buffer[j].position,start_moves[i].position)) break;
if (j >= cluster) {
book_buffer[cluster]=start_moves[i];
book_buffer[cluster].status_played=
book_buffer[cluster].status_played&037700000000;
cluster++;
}
}
/*
----------------------------------------------------------
| |
| first cycle through the root move list, make each |
| move, and see if the resulting hash key is in the book |
| database. |
| |
----------------------------------------------------------
*/
initial_development=(wtm) ? EvaluateDevelopment(tree,1) :
-EvaluateDevelopment(tree,1);
total_moves=0;
nmoves=0;
for (mv=tree->last[0];mv<tree->last[1];mv++) {
common=And(HashKey,mask_16);
MakeMove(tree,1,*mv,wtm);
if (RepetitionCheck(tree,2,ChangeSide(wtm))) {
UnMakeMove(tree,1,*mv,wtm);
return(0);
}
temp_hash_key=Xor(HashKey,wtm_random[wtm]);
temp_hash_key=Or(And(temp_hash_key,Compl(mask_16)),common);
for (i=0;i<cluster;i++) {
if (!Xor(temp_hash_key,book_buffer[i].position)) {
book_status[nmoves]=book_buffer[i].status_played>>24;
bs_played[nmoves]=book_buffer[i].status_playe